﻿#ifndef __INC_PatrickPowell_snprintf_H__
#define __INC_PatrickPowell_snprintf_H__

#if _MSC_VER
#pragma once
#endif

// format read states
#define DP_S_DEFAULT	0
#define DP_S_FLAGS		1
#define DP_S_MIN		2
#define DP_S_DOT		3
#define DP_S_MAX		4
#define DP_S_MOD		5
#define DP_S_CONV		6
#define DP_S_DONE		7

// format flags - Bits
#define DP_F_MINUS      (1 << 0)
#define DP_F_PLUS       (1 << 1)
#define DP_F_SPACE      (1 << 2)
#define DP_F_NUM        (1 << 3)
#define DP_F_ZERO       (1 << 4)
#define DP_F_UP         (1 << 5)
#define DP_F_UNSIGNED   (1 << 6)
#define DP_F_QUOTE		(1 << 7)
#define DP_F_G			(1 << 8)
#define DP_F_E			(1 << 9)

// Conversion Flags
#define DP_C_SHORT		1
#define DP_C_LONG		2
#define DP_C_LLONG		3
#define DP_C_LDOUBLE	4
#define DP_C_SIZE		5
#define DP_C_INTMAX		6
#define DP_C_PTRDIFF	7
#define DP_C_CHAR		8

//
typedef void(*_sn_outfunc)(kpointer, ksize_t*, ksize_t, int);
typedef void(*_sn_clfunc)(kpointer, ksize_t, ksize_t);

//
typedef union _sn_anyval
{
	kshort				h;
	kint				i;
	klong				l;

	kushort				uh;
	kuint				ui;
	kulong				ul;

	kdouble				d;
		
	kchar*				s;
	kwchar*				w;

	// hb only
	ksize_t				sz;

	// C99
	long double			ld;
	intmax_t			im;
	ptrdiff_t			ff;

	//
	kshort*				ph;
	kint*				pi;
	klong*				pl;
	kssize_t*			psz;
	intmax_t*			pim;
	ptrdiff_t*			pff;
} _sn_anyval;

//
extern size_t dopr(_sn_outfunc outfn, _sn_clfunc clfn, kpointer ptr, size_t maxlen, const char *format, va_list args);
extern size_t doprw(_sn_outfunc outfn, _sn_clfunc clfn, kpointer ptr, size_t maxlen, const kwchar *format, va_list args);

#if _SB_64_
#define _fmt_i3264		_fmt_long
#else
#define _fmt_i3264		_fmt_int
#endif

#endif	// __INC_PatrickPowell_snprintf_H__
